🎖️GitЯра🎖️
examples/simple_secure_chat/main.cpp HEAD (0679dbef) Text, 19.85 KB
Tff7b72#Tff7b72include T8b949e<Arduino.h> T8b949e// needed for PlatformIO
Tff7b72#Tff7b72include T8b949e<Mesh.h>
Tff7b72#Tff7b72if defined(NRF52_PLATFORM)
Tff7b72#Tff7b72include T8b949e<InternalFileSystem.h>
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Tff7b72#Tff7b72include T8b949e<LittleFS.h>
Tff7b72#Tff7b72elif defined(ESP32)
Tff7b72#Tff7b72include T8b949e<SPIFFS.h>
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72include T8b949e<helpers/ArduinoHelpers.h>
Tff7b72#Tff7b72include T8b949e<helpers/StaticPoolPacketManager.h>
Tff7b72#Tff7b72include T8b949e<helpers/SimpleMeshTables.h>
Tff7b72#Tff7b72include T8b949e<helpers/IdentityStore.h>
Tff7b72#Tff7b72include T8b949e<RTClib.h>
Tff7b72#Tff7b72include T8b949e<target.h>
T8b949e/* ---------------------------------- CONFIGURATION ------------------------------------- */
Tff7b72#Tff7b72define FIRMWARE_VER_TEXT "v2 (build: 4 Feb 2025)"
Tff7b72#Tff7b72ifndef LORA_FREQ
Tff7b72#Tff7b72define LORA_FREQ 915.0
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_BW
Tff7b72#Tff7b72define LORA_BW 250
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_SF
Tff7b72#Tff7b72define LORA_SF 10
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_CR
Tff7b72#Tff7b72define LORA_CR 5
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef LORA_TX_POWER
Tff7b72#Tff7b72define LORA_TX_POWER 20
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72ifndef MAX_CONTACTS
Tff7b72#Tff7b72define MAX_CONTACTS 100
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72include T8b949e<helpers/BaseChatMesh.h>
Tff7b72#Tff7b72define SEND_TIMEOUT_BASE_MILLIS 500
Tff7b72#Tff7b72define FLOOD_SEND_TIMEOUT_FACTOR 16.0f
Tff7b72#Tff7b72define DIRECT_SEND_PERHOP_FACTOR 6.0f
Tff7b72#Tff7b72define DIRECT_SEND_PERHOP_EXTRA_MILLIS 250
Tff7b72#Tff7b72define PUBLIC_GROUP_PSK "izOH6cXN6mrJ5e26oRXNcg=="
T8b949e// Believe it or not, this std C function is busted on some platforms!
Tff7b72static Tffa657uint32_t Td2a8ff_atoiTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3spTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3n Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3sp Tff7b72&Tff7b72& Tff7b72*Te6edf3sp Tff7b72>Tff7b72= Ta5d6ff'Ta5d6ff0Ta5d6ff' Tff7b72&Tff7b72& Tff7b72*Te6edf3sp Tff7b72<Tff7b72= Ta5d6ff'Ta5d6ff9Ta5d6ff'Tb4b4b4) Tb4b4b4{
Te6edf3n Tff7b72*Tff7b72= T79c0ff10Tb4b4b4;
Te6edf3n Tff7b72+Tff7b72= Tb4b4b4(Tff7b72*Te6edf3spTff7b72+Tff7b72+ Tff7b72- Ta5d6ff'Ta5d6ff0Ta5d6ff'Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3nTb4b4b4;
Tb4b4b4}
T8b949e/* -------------------------------------------------------------------------------------- */
Tff7b72struct T56d364NodePrefs Tb4b4b4{ T8b949e// persisted to file
Tffa657float Te6edf3airtime_factorTb4b4b4;
Tffa657char Te6edf3node_nameTb4b4b4[T79c0ff32Tb4b4b4]Tb4b4b4;
Tffa657double Te6edf3node_latTb4b4b4, Te6edf3node_lonTb4b4b4;
Tffa657float Te6edf3freqTb4b4b4;
Tffa657int8_t Te6edf3tx_power_dbmTb4b4b4;
Tffa657uint8_t Te6edf3unusedTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4;
Tb4b4b4}Tb4b4b4;
Tff7b72class T56d364MyMesh Tff7b72: Tff7b72public Te6edf3BaseChatMeshTb4b4b4, Te6edf3ContactVisitor Tb4b4b4{
Te6edf3FILESYSTEMTff7b72* Te6edf3_fsTb4b4b4;
Te6edf3NodePrefs Te6edf3_prefsTb4b4b4;
Tffa657uint32_t Te6edf3expected_ack_crcTb4b4b4;
Te6edf3ChannelDetailsTff7b72* Te6edf3_publicTb4b4b4;
Tffa657unsigned Tffa657long Te6edf3last_msg_sentTb4b4b4;
Te6edf3ContactInfoTff7b72* Te6edf3curr_recipientTb4b4b4;
Tffa657char Te6edf3commandTb4b4b4[T79c0ff512Tff7b72+T79c0ff10Tb4b4b4]Tb4b4b4;
Tffa657uint8_t Te6edf3tmp_bufTb4b4b4[T79c0ff256Tb4b4b4]Tb4b4b4;
Tffa657char Te6edf3hex_bufTb4b4b4[T79c0ff512Tb4b4b4]Tb4b4b4;
Tff7b72const Tffa657charTff7b72* Td2a8ffgetTypeNameTb4b4b4(Tffa657uint8_t Te6edf3typeTb4b4b4) Tff7b72const Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_CHATTb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffChatTa5d6ff"Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_REPEATERTb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffRepeaterTa5d6ff"Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3ADV_TYPE_ROOMTb4b4b4) Tff7b72return Ta5d6ff"Ta5d6ffRoomTa5d6ff"Tb4b4b4;
Tff7b72return Ta5d6ff"Ta5d6ff??Ta5d6ff"Tb4b4b4; T8b949e// unknown
Tb4b4b4}
Tffa657void Td2a8ffloadContactsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3_fsTff7b72-Tff7b72>Te6edf3existsTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RP2040_PLATFORM)
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3fileTb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3full Tff7b72= Tffa657falseTb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72!Te6edf3fullTb4b4b4) Tb4b4b4{
Te6edf3ContactInfo Te6edf3cTb4b4b4;
Tffa657uint8_t Te6edf3pub_keyTb4b4b4[T79c0ff32Tb4b4b4]Tb4b4b4;
Tffa657uint8_t Te6edf3unusedTb4b4b4;
Tffa657uint32_t Te6edf3reservedTb4b4b4;
Tffa657bool Te6edf3success Tff7b72= Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Te6edf3pub_keyTb4b4b4, T79c0ff32Tb4b4b4) Tff7b72=Tff7b72= T79c0ff32Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3cTb4b4b4.Te6edf3nameTb4b4b4, T79c0ff32Tb4b4b4) Tff7b72=Tff7b72= T79c0ff32Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Te6edf3cTb4b4b4.Te6edf3typeTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Te6edf3cTb4b4b4.Te6edf3flagsTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tff7b72&Te6edf3unusedTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reservedTb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3cTb4b4b4.Te6edf3out_path_lenTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3cTb4b4b4.Te6edf3last_advert_timestampTb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Te6edf3cTb4b4b4.Te6edf3out_pathTb4b4b4, T79c0ff64Tb4b4b4) Tff7b72=Tff7b72= T79c0ff64Tb4b4b4)Tb4b4b4;
Te6edf3cTb4b4b4.Te6edf3gps_lat Tff7b72= Te6edf3cTb4b4b4.Te6edf3gps_lon Tff7b72= T79c0ff0Tb4b4b4; T8b949e// not yet supported
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3successTb4b4b4) Tff7b72breakTb4b4b4; T8b949e// EOF
Te6edf3cTb4b4b4.Te6edf3id Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3IdentityTb4b4b4(Te6edf3pub_keyTb4b4b4)Tb4b4b4;
Te6edf3cTb4b4b4.Te6edf3lastmod Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3addContactTb4b4b4(Te6edf3cTb4b4b4)Tb4b4b4) Te6edf3full Tff7b72= Tffa657trueTb4b4b4;
Tb4b4b4}
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffsaveContactsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(NRF52_PLATFORM)
Te6edf3_fsTff7b72-Tff7b72>Te6edf3removeTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4, Te6edf3FILE_O_WRITETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/contactsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3fileTb4b4b4) Tb4b4b4{
Te6edf3ContactsIterator Te6edf3iter Tff7b72= Te6edf3startContactsIteratorTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3ContactInfo Te6edf3cTb4b4b4;
Tffa657uint8_t Te6edf3unused Tff7b72= T79c0ff0Tb4b4b4;
Tffa657uint32_t Te6edf3reserved Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3iterTb4b4b4.Te6edf3hasNextTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3cTb4b4b4)Tb4b4b4) Tb4b4b4{
Tffa657bool Te6edf3success Tff7b72= Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3cTb4b4b4.Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, T79c0ff32Tb4b4b4) Tff7b72=Tff7b72= T79c0ff32Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3cTb4b4b4.Te6edf3nameTb4b4b4, T79c0ff32Tb4b4b4) Tff7b72=Tff7b72= T79c0ff32Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tff7b72&Te6edf3cTb4b4b4.Te6edf3typeTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tff7b72&Te6edf3cTb4b4b4.Te6edf3flagsTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tff7b72&Te6edf3unusedTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3reservedTb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3cTb4b4b4.Te6edf3out_path_lenTb4b4b4, T79c0ff1Tb4b4b4) Tff7b72=Tff7b72= T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3cTb4b4b4.Te6edf3last_advert_timestampTb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3success Tff7b72= Te6edf3success Tff7b72&Tff7b72& Tb4b4b4(Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3cTb4b4b4.Te6edf3out_pathTb4b4b4, T79c0ff64Tb4b4b4) Tff7b72=Tff7b72= T79c0ff64Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3successTb4b4b4) Tff7b72breakTb4b4b4; T8b949e// write failed
Tb4b4b4}
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffsetClockTb4b4b4(Tffa657uint32_t Te6edf3timestampTb4b4b4) Tb4b4b4{
Tffa657uint32_t Te6edf3curr Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3timestamp Tff7b72> Te6edf3currTb4b4b4) Tb4b4b4{
Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3setCurrentTimeTb4b4b4(Te6edf3timestampTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff (OK - clock set!)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff (ERR: clock cannot go backwards)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Td2a8ffimportCardTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3commandTb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3command Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Te6edf3commandTff7b72+Tff7b72+Tb4b4b4; T8b949e// skip leading spaces
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffmeshcore://Ta5d6ff"Tb4b4b4, T79c0ff11Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3command Tff7b72+Tff7b72= T79c0ff11Tb4b4b4; T8b949e// skip the prefix
Tffa657char Tff7b72*Te6edf3ep Tff7b72= Te6edf3strchrTb4b4b4(Te6edf3commandTb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4; T8b949e// find end of string
Tff7b72while Tb4b4b4(Te6edf3ep Tff7b72> Te6edf3commandTb4b4b4) Tb4b4b4{
Te6edf3epTff7b72-Tff7b72-Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3isHexCharTb4b4b4(Tff7b72*Te6edf3epTb4b4b4)Tb4b4b4) Tff7b72breakTb4b4b4; T8b949e// found tail end of card
Tff7b72*Te6edf3ep Tff7b72= T79c0ff0Tb4b4b4; T8b949e// remove trailing spaces and other junk
Tb4b4b4}
Tffa657int Te6edf3len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3commandTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3len Tff7b72% T79c0ff2 Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3len Tff7b72>Tff7b72>Tff7b72= T79c0ff1Tb4b4b4; T8b949e// halve, for num bytes
Tff7b72if Tb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3fromHexTb4b4b4(Te6edf3tmp_bufTb4b4b4, Te6edf3lenTb4b4b4, Te6edf3commandTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3importContactTb4b4b4(Te6edf3tmp_bufTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff error: invalid formatTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72protectedTff7b72:
Tffa657float Te6edf3getAirtimeBudgetFactorTb4b4b4(Tb4b4b4) Tff7b72const Tff7b72override Tb4b4b4{
Tff7b72return Te6edf3_prefsTb4b4b4.Te6edf3airtime_factorTb4b4b4;
Tb4b4b4}
Tffa657int Te6edf3calcRxDelayTb4b4b4(Tffa657float Te6edf3scoreTb4b4b4, Tffa657uint32_t Te6edf3air_timeTb4b4b4) Tff7b72const Tff7b72override Tb4b4b4{
Tff7b72return T79c0ff0Tb4b4b4; T8b949e// disable rxdelay
Tb4b4b4}
Tffa657bool Te6edf3allowPacketForwardTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3packetTb4b4b4) Tff7b72override Tb4b4b4{
Tff7b72return Tffa657trueTb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3onDiscoveredContactTb4b4b4(Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4, Tffa657bool Te6edf3is_newTb4b4b4, Tffa657uint8_t Te6edf3path_lenTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3pathTb4b4b4) Tff7b72override Tb4b4b4{
T8b949e// TODO: if not in favs, prompt to add as fav(?)
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffADVERT from -> %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3contactTb4b4b4.Te6edf3nameTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff type: %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3getTypeNameTb4b4b4(Te6edf3contactTb4b4b4.Te6edf3typeTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Ta5d6ff"Ta5d6ff public key: Ta5d6ff"Tb4b4b4)Tb4b4b4; Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3printHexTb4b4b4(Te6edf3SerialTb4b4b4, Te6edf3contactTb4b4b4.Te6edf3idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4; Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3saveContactsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3onContactPathUpdatedTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tff7b72override Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffPATH to: %s, path_len=%dTffea00\nTa5d6ff"Tb4b4b4, Te6edf3contactTb4b4b4.Te6edf3nameTb4b4b4, Tb4b4b4(Tffa657uint32_tTb4b4b4) Te6edf3contactTb4b4b4.Te6edf3out_path_lenTb4b4b4)Tb4b4b4;
Te6edf3saveContactsTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3ContactInfoTff7b72* Te6edf3processAckTb4b4b4(Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3dataTb4b4b4) Tff7b72override Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3dataTb4b4b4, Tff7b72&Te6edf3expected_ack_crcTb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// got an ACK from recipient
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff Got ACK! (round trip: %d millis)Tffea00\nTa5d6ff"Tb4b4b4, Te6edf3_msTff7b72-Tff7b72>Te6edf3getMillisTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3last_msg_sentTb4b4b4)Tb4b4b4;
T8b949e// NOTE: the same ACK can be received multiple times!
Te6edf3expected_ack_crc Tff7b72= T79c0ff0Tb4b4b4; T8b949e// reset our expected hash, now that we have received ACK
Tff7b72return Tffa657NULLTb4b4b4; T8b949e// TODO: really should return ContactInfo pointer
Tb4b4b4}
T8b949e//uint32_t crc;
T8b949e//memcpy(&crc, data, 4);
T8b949e//MESH_DEBUG_PRINTLN("unknown ACK received: %08X (expected: %08X)", crc, expected_ack_crc);
Tff7b72return Tffa657NULLTb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3onMessageRecvTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3fromTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657char Tff7b72*Te6edf3textTb4b4b4) Tff7b72override Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff(%s) MSG -> from %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4) Tff7b72? Ta5d6ff"Ta5d6ffDIRECTTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffFLOODTa5d6ff"Tb4b4b4, Te6edf3fromTb4b4b4.Te6edf3nameTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3textTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Te6edf3textTb4b4b4, Ta5d6ff"Ta5d6ffclock syncTa5d6ff"Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// special text command
Te6edf3setClockTb4b4b4(Te6edf3sender_timestamp Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3onCommandDataRecvTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3fromTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657char Tff7b72*Te6edf3textTb4b4b4) Tff7b72override Tb4b4b4{
Tb4b4b4}
Tffa657void Te6edf3onSignedMessageRecvTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3fromTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657uint8_t Tff7b72*Te6edf3sender_prefixTb4b4b4, Tff7b72const Tffa657char Tff7b72*Te6edf3textTb4b4b4) Tff7b72override Tb4b4b4{
Tb4b4b4}
Tffa657void Te6edf3onChannelMessageRecvTb4b4b4(Tff7b72const Te6edf3meshTff7b72:Tff7b72:Te6edf3GroupChannelTff7b72& Te6edf3channelTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3PacketTff7b72* Te6edf3pktTb4b4b4, Tffa657uint32_t Te6edf3timestampTb4b4b4, Tff7b72const Tffa657char Tff7b72*Te6edf3textTb4b4b4) Tff7b72override Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pktTff7b72-Tff7b72>Te6edf3isRouteDirectTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffPUBLIC CHANNEL MSG -> (Direct!)Tffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffPUBLIC CHANNEL MSG -> (Flood) hops %dTffea00\nTa5d6ff"Tb4b4b4, Te6edf3pktTff7b72-Tff7b72>Te6edf3path_lenTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3textTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint8_t Te6edf3onContactRequestTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4, Tffa657uint32_t Te6edf3sender_timestampTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657uint8_t Te6edf3lenTb4b4b4, Tffa657uint8_tTff7b72* Te6edf3replyTb4b4b4) Tff7b72override Tb4b4b4{
Tff7b72return T79c0ff0Tb4b4b4; T8b949e// unknown
Tb4b4b4}
Tffa657void Te6edf3onContactResponseTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4, Tff7b72const Tffa657uint8_tTff7b72* Te6edf3dataTb4b4b4, Tffa657uint8_t Te6edf3lenTb4b4b4) Tff7b72override Tb4b4b4{
T8b949e// not supported
Tb4b4b4}
Tffa657uint32_t Te6edf3calcFloodTimeoutMillisForTb4b4b4(Tffa657uint32_t Te6edf3pkt_airtime_millisTb4b4b4) Tff7b72const Tff7b72override Tb4b4b4{
Tff7b72return Te6edf3SEND_TIMEOUT_BASE_MILLIS Tff7b72+ Tb4b4b4(Te6edf3FLOOD_SEND_TIMEOUT_FACTOR Tff7b72* Te6edf3pkt_airtime_millisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657uint32_t Te6edf3calcDirectTimeoutMillisForTb4b4b4(Tffa657uint32_t Te6edf3pkt_airtime_millisTb4b4b4, Tffa657uint8_t Te6edf3path_lenTb4b4b4) Tff7b72const Tff7b72override Tb4b4b4{
Tffa657uint8_t Te6edf3path_hash_count Tff7b72= Te6edf3path_len Tff7b72& T79c0ff63Tb4b4b4;
Tff7b72return Te6edf3SEND_TIMEOUT_BASE_MILLIS Tff7b72+
Tb4b4b4( Tb4b4b4(Te6edf3pkt_airtime_millisTff7b72*Te6edf3DIRECT_SEND_PERHOP_FACTOR Tff7b72+ Te6edf3DIRECT_SEND_PERHOP_EXTRA_MILLISTb4b4b4) Tff7b72* Tb4b4b4(Te6edf3path_hash_count Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3onSendTimeoutTb4b4b4(Tb4b4b4) Tff7b72override Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff ERROR: timed out, no ACK.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72publicTff7b72:
Te6edf3MyMeshTb4b4b4(Te6edf3meshTff7b72:Tff7b72:Te6edf3RadioTff7b72& Te6edf3radioTb4b4b4, Te6edf3StdRNGTff7b72& Te6edf3rngTb4b4b4, Te6edf3meshTff7b72:Tff7b72:Te6edf3RTCClockTff7b72& Te6edf3rtcTb4b4b4, Te6edf3SimpleMeshTablesTff7b72& Te6edf3tablesTb4b4b4)
Tff7b72: Te6edf3BaseChatMeshTb4b4b4(Te6edf3radioTb4b4b4, Tff7b72*Tff7b72new Te6edf3ArduinoMillisTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3rngTb4b4b4, Te6edf3rtcTb4b4b4, Tff7b72*Tff7b72new Te6edf3StaticPoolPacketManagerTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4, Te6edf3tablesTb4b4b4)
Tb4b4b4{
T8b949e// defaults
Te6edf3memsetTb4b4b4(Tff7b72&Te6edf3_prefsTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3airtime_factor Tff7b72= T79c0ff1.0Tb4b4b4;
Te6edf3strcpyTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Ta5d6ff"Ta5d6ffNONAMETa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3freq Tff7b72= Te6edf3LORA_FREQTb4b4b4;
Te6edf3_prefsTb4b4b4.Te6edf3tx_power_dbm Tff7b72= Te6edf3LORA_TX_POWERTb4b4b4;
Te6edf3commandTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3curr_recipient Tff7b72= Tffa657NULLTb4b4b4;
Tb4b4b4}
Tffa657float Te6edf3getFreqPrefTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{ Tff7b72return Te6edf3_prefsTb4b4b4.Te6edf3freqTb4b4b4; Tb4b4b4}
Tffa657int8_t Te6edf3getTxPowerPrefTb4b4b4(Tb4b4b4) Tff7b72const Tb4b4b4{ Tff7b72return Te6edf3_prefsTb4b4b4.Te6edf3tx_power_dbmTb4b4b4; Tb4b4b4}
Tffa657void Te6edf3beginTb4b4b4(Te6edf3FILESYSTEMTff7b72& Te6edf3fsTb4b4b4) Tb4b4b4{
Te6edf3_fs Tff7b72= Tff7b72&Te6edf3fsTb4b4b4;
Te6edf3BaseChatMeshTff7b72:Tff7b72:Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(NRF52_PLATFORM)
Te6edf3IdentityStore Te6edf3storeTb4b4b4(Te6edf3fsTb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Te6edf3IdentityStore Te6edf3storeTb4b4b4(Te6edf3fsTb4b4b4, Ta5d6ff"Ta5d6ff/identityTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3storeTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3IdentityStore Te6edf3storeTb4b4b4(Te6edf3fsTb4b4b4, Ta5d6ff"Ta5d6ff/identityTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3storeTb4b4b4.Te6edf3loadTb4b4b4(Ta5d6ff"Ta5d6ff_mainTa5d6ff"Tb4b4b4, Te6edf3self_idTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// legacy: node_name was from identity file
T8b949e// Need way to get some entropy to seed RNG
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ffPress ENTER to generate key:Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tffa657char Te6edf3c Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3c Tff7b72!Tff7b72= Ta5d6ff'Ta5d6ff\nTa5d6ff'Tb4b4b4) Tb4b4b4{ T8b949e// wait for ENTER to be pressed
Tff7b72if Tb4b4b4(Te6edf3SerialTb4b4b4.Te6edf3availableTb4b4b4(Tb4b4b4)Tb4b4b4) Te6edf3c Tff7b72= Te6edf3SerialTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4(Tb4b4b4(Te6edf3StdRNG Tff7b72*Tb4b4b4)Te6edf3getRNGTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72-Tff7b72>Te6edf3beginTb4b4b4(Te6edf3millisTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3self_id Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3LocalIdentityTb4b4b4(Te6edf3getRNGTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4; T8b949e// create new random identity
Tffa657int Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3count Tff7b72< T79c0ff10 Tff7b72&Tff7b72& Tb4b4b4(Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= T79c0ff0x00 Tff7b72|Tff7b72| Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4)Tb4b4b4) Tb4b4b4{ T8b949e// reserved id hashes
Te6edf3self_id Tff7b72= Te6edf3meshTff7b72:Tff7b72:Te6edf3LocalIdentityTb4b4b4(Te6edf3getRNGTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4; Te6edf3countTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Te6edf3storeTb4b4b4.Te6edf3saveTb4b4b4(Ta5d6ff"Ta5d6ff_mainTa5d6ff"Tb4b4b4, Te6edf3self_idTb4b4b4)Tb4b4b4;
Tb4b4b4}
T8b949e// load persisted prefs
Tff7b72if Tb4b4b4(Te6edf3_fsTff7b72-Tff7b72>Te6edf3existsTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(RP2040_PLATFORM)
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3fileTb4b4b4) Tb4b4b4{
Te6edf3fileTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4(Tffa657uint8_t Tff7b72*Tb4b4b4) Tff7b72&Te6edf3_prefsTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3loadContactsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3_public Tff7b72= Te6edf3addChannelTb4b4b4(Ta5d6ff"Ta5d6ffPublicTa5d6ff"Tb4b4b4, Te6edf3PUBLIC_GROUP_PSKTb4b4b4)Tb4b4b4; T8b949e// pre-configure Andy's public channel
Tb4b4b4}
Tffa657void Te6edf3savePrefsTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if defined(NRF52_PLATFORM)
Te6edf3_fsTff7b72-Tff7b72>Te6edf3removeTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4, Te6edf3FILE_O_WRITETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3File Te6edf3file Tff7b72= Te6edf3_fsTff7b72-Tff7b72>Te6edf3openTb4b4b4(Ta5d6ff"Ta5d6ff/node_prefsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4, Tffa657trueTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3fileTb4b4b4) Tb4b4b4{
Te6edf3fileTb4b4b4.Te6edf3writeTb4b4b4(Tb4b4b4(Tff7b72const Tffa657uint8_t Tff7b72*Tb4b4b4)Tff7b72&Te6edf3_prefsTb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fileTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3showWelcomeTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff===== MeshCore Chat Terminal =====Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffWELCOME %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4)Tb4b4b4;
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3printHexTb4b4b4(Te6edf3SerialTb4b4b4, Te6edf3self_idTb4b4b4.Te6edf3pub_keyTb4b4b4, Te6edf3PUB_KEY_SIZETb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff (enter 'help' for basic commands)Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3sendSelfAdvertTb4b4b4(Tffa657int Te6edf3delay_millisTb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createSelfAdvertTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_latTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_lonTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Te6edf3sendFloodTb4b4b4(Te6edf3pktTb4b4b4, Te6edf3delay_millisTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
T8b949e// ContactVisitor
Tffa657void Te6edf3onContactVisitTb4b4b4(Tff7b72const Te6edf3ContactInfoTff7b72& Te6edf3contactTb4b4b4) Tff7b72override Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff %s - Ta5d6ff"Tb4b4b4, Te6edf3contactTb4b4b4.Te6edf3nameTb4b4b4)Tb4b4b4;
Tffa657char Te6edf3tmpTb4b4b4[T79c0ff40Tb4b4b4]Tb4b4b4;
Tffa657int32_t Te6edf3secs Tff7b72= Te6edf3contactTb4b4b4.Te6edf3last_advert_timestamp Tff7b72- Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3AdvertTimeHelperTff7b72:Tff7b72:Te6edf3formatRelativeTimeDiffTb4b4b4(Te6edf3tmpTb4b4b4, Te6edf3secsTb4b4b4, Tffa657falseTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Te6edf3tmpTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tffa657void Te6edf3handleCommandTb4b4b4(Tff7b72const Tffa657charTff7b72* Te6edf3commandTb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(Tff7b72*Te6edf3command Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Te6edf3commandTff7b72+Tff7b72+Tb4b4b4; T8b949e// skip leading spaces
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffsend Ta5d6ff"Tb4b4b4, T79c0ff5Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3curr_recipientTb4b4b4) Tb4b4b4{
Tff7b72const Tffa657char Tff7b72*Te6edf3text Tff7b72= Tff7b72&Te6edf3commandTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3est_timeoutTb4b4b4;
Tffa657int Te6edf3result Tff7b72= Te6edf3sendMessageTb4b4b4(Tff7b72*Te6edf3curr_recipientTb4b4b4, Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff0Tb4b4b4, Te6edf3textTb4b4b4, Te6edf3expected_ack_crcTb4b4b4, Te6edf3est_timeoutTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3result Tff7b72=Tff7b72= Te6edf3MSG_SEND_FAILEDTb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff ERROR: unable to send.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3last_msg_sent Tff7b72= Te6edf3_msTff7b72-Tff7b72>Te6edf3getMillisTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff (message sent - %s)Tffea00\nTa5d6ff"Tb4b4b4, Te6edf3result Tff7b72=Tff7b72= Te6edf3MSG_SEND_SENT_FLOOD Tff7b72? Ta5d6ff"Ta5d6ffFLOODTa5d6ff" Tff7b72: Ta5d6ff"Ta5d6ffDIRECTTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff ERROR: no recipient selected (use 'to' cmd).Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffpublic Ta5d6ff"Tb4b4b4, T79c0ff7Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// send GroupChannel msg
Tffa657uint8_t Te6edf3tempTb4b4b4[T79c0ff5Tff7b72+Te6edf3MAX_TEXT_LENTff7b72+T79c0ff32Tb4b4b4]Tb4b4b4;
Tffa657uint32_t Te6edf3timestamp Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3memcpyTb4b4b4(Te6edf3tempTb4b4b4, Tff7b72&Te6edf3timestampTb4b4b4, T79c0ff4Tb4b4b4)Tb4b4b4; T8b949e// mostly an extra blob to help make packet_hash unique
Te6edf3tempTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// attempt and flags
Te6edf3sprintfTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ff%s: %sTa5d6ff"Tb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Tff7b72&Te6edf3commandTb4b4b4[T79c0ff7Tb4b4b4]Tb4b4b4)Tb4b4b4; T8b949e// <sender>: <msg>
Te6edf3tempTb4b4b4[T79c0ff5 Tff7b72+ Te6edf3MAX_TEXT_LENTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// truncate if too long
Tffa657int Te6edf3len Tff7b72= Te6edf3strlenTb4b4b4(Tb4b4b4(Tffa657char Tff7b72*Tb4b4b4) Tff7b72&Te6edf3tempTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createGroupDatagramTb4b4b4(Te6edf3PAYLOAD_TYPE_GRP_TXTTb4b4b4, Te6edf3_publicTff7b72-Tff7b72>Te6edf3channelTb4b4b4, Te6edf3tempTb4b4b4, T79c0ff5 Tff7b72+ Te6edf3lenTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Te6edf3sendFloodTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff Sent.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff ERROR: unable to sendTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6fflistTa5d6ff"Tb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// show Contact list, by most recent
Tffa657int Te6edf3n Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3commandTb4b4b4[T79c0ff4Tb4b4b4] Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4) Tb4b4b4{ T8b949e// optional param, last 'N'
Te6edf3n Tff7b72= Te6edf3atoiTb4b4b4(Tff7b72&Te6edf3commandTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3scanRecentContactsTb4b4b4(Te6edf3nTb4b4b4, Tff7b72thisTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffclockTa5d6ff"Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// show current time
Tffa657uint32_t Te6edf3now Tff7b72= Te6edf3getRTCClockTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72>Te6edf3getCurrentTimeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3DateTime Te6edf3dt Tff7b72= Te6edf3DateTimeTb4b4b4(Te6edf3nowTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4( Ta5d6ff"Ta5d6ff%02d:%02d - %d/%d/%d UTCTffea00\nTa5d6ff"Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3hourTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3minuteTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3dayTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3monthTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3dtTb4b4b4.Te6edf3yearTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6fftime Ta5d6ff"Tb4b4b4, T79c0ff5Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// set time (to epoch seconds)
Tffa657uint32_t Te6edf3secs Tff7b72= Te6edf3_atoiTb4b4b4(Tff7b72&Te6edf3commandTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3setClockTb4b4b4(Te6edf3secsTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffto Ta5d6ff"Tb4b4b4, T79c0ff3Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// set current recipient
Te6edf3curr_recipient Tff7b72= Te6edf3searchContactsByPrefixTb4b4b4(Tff7b72&Te6edf3commandTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3curr_recipientTb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff Recipient %s now selected.Tffea00\nTa5d6ff"Tb4b4b4, Te6edf3curr_recipientTff7b72-Tff7b72>Te6edf3nameTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff Error: Name prefix not found.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6fftoTa5d6ff"Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{ T8b949e// show current recipient
Tff7b72if Tb4b4b4(Te6edf3curr_recipientTb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff Current: %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3curr_recipientTff7b72-Tff7b72>Te6edf3nameTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff Err: no recipient selectedTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffadvertTa5d6ff"Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createSelfAdvertTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_latTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_lonTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Te6edf3sendZeroHopTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff (advert sent, zero hop).Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff ERR: unable to sendTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3strcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffreset pathTa5d6ff"Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3curr_recipientTb4b4b4) Tb4b4b4{
Te6edf3resetPathToTb4b4b4(Tff7b72*Te6edf3curr_recipientTb4b4b4)Tb4b4b4;
Te6edf3saveContactsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff Done.Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffcardTa5d6ff"Tb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ffHello %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4)Tb4b4b4;
Tff7b72auto Te6edf3pkt Tff7b72= Te6edf3createSelfAdvertTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_latTb4b4b4, Te6edf3_prefsTb4b4b4.Te6edf3node_lonTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3pktTb4b4b4) Tb4b4b4{
Tffa657uint8_t Te6edf3len Tff7b72= Te6edf3pktTff7b72-Tff7b72>Te6edf3writeToTb4b4b4(Te6edf3tmp_bufTb4b4b4)Tb4b4b4;
Te6edf3releasePacketTb4b4b4(Te6edf3pktTb4b4b4)Tb4b4b4; T8b949e// undo the obtainNewPacket()
Te6edf3meshTff7b72:Tff7b72:Te6edf3UtilsTff7b72:Tff7b72:Te6edf3toHexTb4b4b4(Te6edf3hex_bufTb4b4b4, Te6edf3tmp_bufTb4b4b4, Te6edf3lenTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ffYour MeshCore biz card:Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Ta5d6ff"Ta5d6ffmeshcore://Ta5d6ff"Tb4b4b4)Tb4b4b4; Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Te6edf3hex_bufTb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff ErrorTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffimport Ta5d6ff"Tb4b4b4, T79c0ff7Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3importCardTb4b4b4(Tff7b72&Te6edf3commandTb4b4b4[T79c0ff7Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffset Ta5d6ff"Tb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72const Tffa657charTff7b72* Te6edf3config Tff7b72= Tff7b72&Te6edf3commandTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3configTb4b4b4, Ta5d6ff"Ta5d6ffaf Ta5d6ff"Tb4b4b4, T79c0ff3Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_prefsTb4b4b4.Te6edf3airtime_factor Tff7b72= Te6edf3atofTb4b4b4(Tff7b72&Te6edf3configTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3savePrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff OKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3configTb4b4b4, Ta5d6ff"Ta5d6ffname Ta5d6ff"Tb4b4b4, T79c0ff5Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3StrHelperTff7b72:Tff7b72:Te6edf3strncpyTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4, Tff7b72&Te6edf3configTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3_prefsTb4b4b4.Te6edf3node_nameTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3savePrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff OKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3configTb4b4b4, Ta5d6ff"Ta5d6fflat Ta5d6ff"Tb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_prefsTb4b4b4.Te6edf3node_lat Tff7b72= Te6edf3atofTb4b4b4(Tff7b72&Te6edf3configTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3savePrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff OKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3configTb4b4b4, Ta5d6ff"Ta5d6fflon Ta5d6ff"Tb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_prefsTb4b4b4.Te6edf3node_lon Tff7b72= Te6edf3atofTb4b4b4(Tff7b72&Te6edf3configTb4b4b4[T79c0ff4Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3savePrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff OKTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3configTb4b4b4, Ta5d6ff"Ta5d6fftx Ta5d6ff"Tb4b4b4, T79c0ff3Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_prefsTb4b4b4.Te6edf3tx_power_dbm Tff7b72= Te6edf3atoiTb4b4b4(Tff7b72&Te6edf3configTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3savePrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff OK - reboot to applyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3configTb4b4b4, Ta5d6ff"Ta5d6fffreq Ta5d6ff"Tb4b4b4, T79c0ff5Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3_prefsTb4b4b4.Te6edf3freq Tff7b72= Te6edf3atofTb4b4b4(Tff7b72&Te6edf3configTb4b4b4[T79c0ff5Tb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3savePrefsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff OK - reboot to applyTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printfTb4b4b4(Ta5d6ff"Ta5d6ff ERROR: unknown config: %sTffea00\nTa5d6ff"Tb4b4b4, Te6edf3configTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffverTa5d6ff"Tb4b4b4, T79c0ff3Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Te6edf3FIRMWARE_VER_TEXTTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3memcmpTb4b4b4(Te6edf3commandTb4b4b4, Ta5d6ff"Ta5d6ffhelpTa5d6ff"Tb4b4b4, T79c0ff4Tb4b4b4) Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ffCommands:Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff set {name|lat|lon|freq|tx|af} {value}Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff cardTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff import {biz card}Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff clockTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff time <epoch-seconds>Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff list {n}Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff to <recipient name or prefix>Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff toTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff send <text>Ta5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff advertTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff reset pathTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Ta5d6ff"Ta5d6ff public <text>Ta5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Ta5d6ff"Ta5d6ff ERROR: unknown command: Ta5d6ff"Tb4b4b4)Tb4b4b4; Te6edf3SerialTb4b4b4.Te6edf3printlnTb4b4b4(Te6edf3commandTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tffa657void Te6edf3loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3BaseChatMeshTff7b72:Tff7b72:Te6edf3loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tffa657int Te6edf3len Tff7b72= Te6edf3strlenTb4b4b4(Te6edf3commandTb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3SerialTb4b4b4.Te6edf3availableTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3len Tff7b72< Tff7b72sizeofTb4b4b4(Te6edf3commandTb4b4b4)T79c0ff-1Tb4b4b4) Tb4b4b4{
Tffa657char Te6edf3c Tff7b72= Te6edf3SerialTb4b4b4.Te6edf3readTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3c Tff7b72!Tff7b72= Ta5d6ff'Ta5d6ff\nTa5d6ff'Tb4b4b4) Tb4b4b4{
Te6edf3commandTb4b4b4[Te6edf3lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3cTb4b4b4;
Te6edf3commandTb4b4b4[Te6edf3lenTb4b4b4] Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Te6edf3SerialTb4b4b4.Te6edf3printTb4b4b4(Te6edf3cTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3len Tff7b72=Tff7b72= Tff7b72sizeofTb4b4b4(Te6edf3commandTb4b4b4)T79c0ff-1Tb4b4b4) Tb4b4b4{ T8b949e// command buffer full
Te6edf3commandTb4b4b4[Tff7b72sizeofTb4b4b4(Te6edf3commandTb4b4b4)T79c0ff-1Tb4b4b4] Tff7b72= Ta5d6ff'Ta5d6ff\rTa5d6ff'Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3len Tff7b72> T79c0ff0 Tff7b72&Tff7b72& Te6edf3commandTb4b4b4[Te6edf3len Tff7b72- T79c0ff1Tb4b4b4] Tff7b72=Tff7b72= Ta5d6ff'Ta5d6ff\rTa5d6ff'Tb4b4b4) Tb4b4b4{ T8b949e// received complete line
Te6edf3commandTb4b4b4[Te6edf3len Tff7b72- T79c0ff1Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// replace newline with C string null terminator
Te6edf3handleCommandTb4b4b4(Te6edf3commandTb4b4b4)Tb4b4b4;
Te6edf3commandTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72= T79c0ff0Tb4b4b4; T8b949e// reset command buffer
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4;
Te6edf3StdRNG Te6edf3fast_rngTb4b4b4;
Te6edf3SimpleMeshTables Te6edf3tablesTb4b4b4;
Te6edf3MyMesh Td2a8ffthe_meshTb4b4b4(Te6edf3radio_driverTb4b4b4, Te6edf3fast_rngTb4b4b4, Te6edf3rtc_clockTb4b4b4, Te6edf3tablesTb4b4b4)Tb4b4b4;
Tffa657void Td2a8ffhaltTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(T79c0ff1Tb4b4b4) Tb4b4b4;
Tb4b4b4}
Tffa657void Td2a8ffsetupTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3SerialTb4b4b4.Te6edf3beginTb4b4b4(T79c0ff115200Tb4b4b4)Tb4b4b4;
Te6edf3boardTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef HAS_EXTERNAL_WATCHDOG
Te6edf3external_watchdogTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3radio_initTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3haltTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4}
Te6edf3fast_rngTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3radio_driverTb4b4b4.Te6edf3getRngSeedTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if defined(NRF52_PLATFORM)
Te6edf3InternalFSTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3the_meshTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3InternalFSTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(RP2040_PLATFORM)
Te6edf3LittleFSTb4b4b4.Te6edf3beginTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3the_meshTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3LittleFSTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif defined(ESP32)
Te6edf3SPIFFSTb4b4b4.Te6edf3beginTb4b4b4(Tffa657trueTb4b4b4)Tb4b4b4;
Te6edf3the_meshTb4b4b4.Te6edf3beginTb4b4b4(Te6edf3SPIFFSTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tff7b72#Tff7b72error "need to define filesystem"
Tff7b72#Tff7b72endif
Te6edf3radio_driverTb4b4b4.Te6edf3setParamsTb4b4b4(Te6edf3the_meshTb4b4b4.Te6edf3getFreqPrefTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3LORA_BWTb4b4b4, Te6edf3LORA_SFTb4b4b4, Te6edf3LORA_CRTb4b4b4)Tb4b4b4;
Te6edf3radio_driverTb4b4b4.Te6edf3setTxPowerTb4b4b4(Te6edf3the_meshTb4b4b4.Te6edf3getTxPowerPrefTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3the_meshTb4b4b4.Te6edf3showWelcomeTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// send out initial Advertisement to the mesh
Tff7b72#Tff7b72if ENABLE_ADVERT_ON_BOOT == 1
Te6edf3the_meshTb4b4b4.Te6edf3sendSelfAdvertTb4b4b4(T79c0ff1200Tb4b4b4)Tb4b4b4; T8b949e// add slight delay
Tff7b72#Tff7b72endif
Tb4b4b4}
Tffa657void Td2a8ffloopTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3the_meshTb4b4b4.Te6edf3loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3rtc_clockTb4b4b4.Te6edf3tickTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72ifdef HAS_EXTERNAL_WATCHDOG
Te6edf3external_watchdogTb4b4b4.Te6edf3loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.27s